home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / BNU22SR1.ZIP / src / binutils.2 / gprof / tahoe.c < prev    next >
C/C++ Source or Header  |  1993-05-30  |  8KB  |  336 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that: (1) source distributions retain this entire copyright
  7.  * notice and comment, and (2) distributions including binaries display
  8.  * the following acknowledgement:  ``This product includes software
  9.  * developed by the University of California, Berkeley and its contributors''
  10.  * in the documentation or other materials provided with the distribution
  11.  * and in all advertising materials mentioning features or use of this
  12.  * software. Neither the name of the University nor the names of its
  13.  * contributors may be used to endorse or promote products derived
  14.  * from this software without specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  16.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  17.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19.  
  20. #ifndef lint
  21. static char sccsid[] = "@(#)tahoe.c    1.5 (Berkeley) 6/1/90";
  22. #endif /* not lint */
  23.  
  24. #include    "gprof.h"
  25.  
  26.     /*
  27.      *    a namelist entry to be the child of indirect callf
  28.      */
  29. nltype    indirectchild = {
  30.     "(*)" ,                /* the name */
  31.     (unsigned long) 0 ,        /* the pc entry point */
  32.     (unsigned long) 0 ,        /* entry point aligned to histogram */
  33.     (double) 0.0 ,            /* ticks in this routine */
  34.     (double) 0.0 ,            /* cumulative ticks in children */
  35.     (long) 0 ,            /* how many times called */
  36.     (long) 0 ,            /* how many calls to self */
  37.     (double) 1.0 ,            /* propagation fraction */
  38.     (double) 0.0 ,            /* self propagation time */
  39.     (double) 0.0 ,            /* child propagation time */
  40.     (bool) 0 ,            /* print flag */
  41.     (int) 0 ,            /* index in the graph list */
  42.     (int) 0 ,             /* graph call chain top-sort order */
  43.     (int) 0 ,            /* internal number of cycle on */
  44.     (struct nl *) &indirectchild ,    /* pointer to head of cycle */
  45.     (struct nl *) 0 ,        /* pointer to next member of cycle */
  46.     (arctype *) 0 ,            /* list of caller arcs */
  47.     (arctype *) 0             /* list of callee arcs */
  48.     };
  49.  
  50. operandenum
  51. operandmode( modep )
  52.     unsigned char    *modep;
  53. {
  54.     long    usesreg = ((long)*modep) & 0xf;
  55.     
  56.     switch ( ((long)*modep) >> 4 ) {
  57.     case 0:
  58.     case 1:
  59.     case 2:
  60.     case 3:
  61.         return literal;
  62.     case 4:
  63.         return indexed;
  64.     case 5:
  65.         return reg;
  66.     case 6:
  67.         return regdef;
  68.     case 7:
  69.         return autodec;
  70.     case 8:
  71.         return ( usesreg != 0xe ? autoinc : immediate );
  72.     case 9:
  73.         return ( usesreg != PC ? autoincdef : absolute );
  74.     case 10:
  75.         return ( usesreg != PC ? bytedisp : byterel );
  76.     case 11:
  77.         return ( usesreg != PC ? bytedispdef : bytereldef );
  78.     case 12:
  79.         return ( usesreg != PC ? worddisp : wordrel );
  80.     case 13:
  81.         return ( usesreg != PC ? worddispdef : wordreldef );
  82.     case 14:
  83.         return ( usesreg != PC ? longdisp : longrel );
  84.     case 15:
  85.         return ( usesreg != PC ? longdispdef : longreldef );
  86.     }
  87.     /* NOTREACHED */
  88. }
  89.  
  90. char *
  91. operandname( mode )
  92.     operandenum    mode;
  93. {
  94.     
  95.     switch ( mode ) {
  96.     case literal:
  97.         return "literal";
  98.     case indexed:
  99.         return "indexed";
  100.     case reg:
  101.         return "register";
  102.     case regdef:
  103.         return "register deferred";
  104.     case autodec:
  105.         return "autodecrement";
  106.     case autoinc:
  107.         return "autoincrement";
  108.     case autoincdef:
  109.         return "autoincrement deferred";
  110.     case bytedisp:
  111.         return "byte displacement";
  112.     case bytedispdef:
  113.         return "byte displacement deferred";
  114.     case byterel:
  115.         return "byte relative";
  116.     case bytereldef:
  117.         return "byte relative deferred";
  118.     case worddisp:
  119.         return "word displacement";
  120.     case worddispdef:
  121.         return "word displacement deferred";
  122.     case wordrel:
  123.         return "word relative";
  124.     case wordreldef:
  125.         return "word relative deferred";
  126.     case immediate:
  127.         return "immediate";
  128.     case absolute:
  129.         return "absolute";
  130.     case longdisp:
  131.         return "long displacement";
  132.     case longdispdef:
  133.         return "long displacement deferred";
  134.     case longrel:
  135.         return "long relative";
  136.     case longreldef:
  137.         return "long relative deferred";
  138.     }
  139.     /* NOTREACHED */
  140. }
  141.  
  142. long
  143. operandlength( modep )
  144.     unsigned char    *modep;
  145. {
  146.     
  147.     switch ( operandmode( modep ) ) {
  148.     case literal:
  149.     case reg:
  150.     case regdef:
  151.     case autodec:
  152.     case autoinc:
  153.     case autoincdef:
  154.         return 1;
  155.     case bytedisp:
  156.     case bytedispdef:
  157.     case byterel:
  158.     case bytereldef:
  159.         return 2;
  160.     case worddisp:
  161.     case worddispdef:
  162.     case wordrel:
  163.     case wordreldef:
  164.         return 3;
  165.     case immediate:
  166.     case absolute:
  167.     case longdisp:
  168.     case longdispdef:
  169.     case longrel:
  170.     case longreldef:
  171.         return 5;
  172.     case indexed:
  173.         return 1+operandlength( modep + 1 );
  174.     }
  175.     /* NOTREACHED */
  176. }
  177.  
  178. unsigned long
  179. reladdr( modep )
  180.     char    *modep;
  181. {
  182.     operandenum    mode = operandmode( modep );
  183.     char    *cp;
  184.     short    *sp;
  185.     long    *lp;
  186.     int        i;
  187.     long    value = 0;
  188.  
  189.     cp = modep;
  190.     cp += 1;            /* skip over the mode */
  191.     switch ( mode ) {
  192.     default:
  193.         fprintf( stderr , "[reladdr] not relative address\n" );
  194.         return (unsigned long) modep;
  195.     case byterel:
  196.         return (unsigned long) ( cp + sizeof *cp + *cp );
  197.     case wordrel:
  198.         for (i = 0; i < sizeof *sp; i++)
  199.         value = (value << 8) + (cp[i] & 0xff);
  200.         return (unsigned long) ( cp + sizeof *sp + value );
  201.     case longrel:
  202.         for (i = 0; i < sizeof *lp; i++)
  203.         value = (value << 8) + (cp[i] & 0xff);
  204.         return (unsigned long) ( cp + sizeof *lp + value );
  205.     }
  206. }
  207.  
  208. findcall( parentp , p_lowpc , p_highpc )
  209.     nltype        *parentp;
  210.     unsigned long    p_lowpc;
  211.     unsigned long    p_highpc;
  212. {
  213.     unsigned char    *instructp;
  214.     long        length;
  215.     nltype        *childp;
  216.     operandenum        mode;
  217.     operandenum        firstmode;
  218.     unsigned long    destpc;
  219.  
  220.     if ( textspace == 0 ) {
  221.     return;
  222.     }
  223.     if ( p_lowpc < s_lowpc ) {
  224.     p_lowpc = s_lowpc;
  225.     }
  226.     if ( p_highpc > s_highpc ) {
  227.     p_highpc = s_highpc;
  228.     }
  229. #   ifdef DEBUG
  230.     if ( debug & CALLDEBUG ) {
  231.         printf( "[findcall] %s: 0x%x to 0x%x\n" ,
  232.             parentp -> name , p_lowpc , p_highpc );
  233.     }
  234. #   endif DEBUG
  235.     for (   instructp = textspace + p_lowpc ;
  236.         instructp < textspace + p_highpc ;
  237.         instructp += length ) {
  238.     length = 1;
  239.     if ( *instructp == CALLF ) {
  240.         /*
  241.          *    maybe a callf, better check it out.
  242.          *    skip the count of the number of arguments.
  243.          */
  244. #        ifdef DEBUG
  245.         if ( debug & CALLDEBUG ) {
  246.             printf( "[findcall]\t0x%x:callf" , instructp - textspace );
  247.         }
  248. #        endif DEBUG
  249.         firstmode = operandmode( instructp+length );
  250.         switch ( firstmode ) {
  251.         case literal:
  252.         case immediate:
  253.             break;
  254.         default:
  255.             goto botched;
  256.         }
  257.         length += operandlength( instructp+length );
  258.         mode = operandmode( instructp + length );
  259. #        ifdef DEBUG
  260.         if ( debug & CALLDEBUG ) {
  261.             printf( "\tfirst operand is %s", operandname( firstmode ) );
  262.             printf( "\tsecond operand is %s\n" , operandname( mode ) );
  263.         }
  264. #        endif DEBUG
  265.         switch ( mode ) {
  266.         case regdef:
  267.         case bytedispdef:
  268.         case worddispdef:
  269.         case longdispdef:
  270.         case bytereldef:
  271.         case wordreldef:
  272.         case longreldef:
  273.             /*
  274.              *    indirect call: call through pointer
  275.              *    either    *d(r)    as a parameter or local
  276.              *        (r)    as a return value
  277.              *        *f    as a global pointer
  278.              *    [are there others that we miss?,
  279.              *     e.g. arrays of pointers to functions???]
  280.              */
  281.             addarc( parentp , &indirectchild , (long) 0 );
  282.             length += operandlength( instructp + length );
  283.             continue;
  284.         case byterel:
  285.         case wordrel:
  286.         case longrel:
  287.             /*
  288.              *    regular pc relative addressing
  289.              *    check that this is the address of 
  290.              *    a function.
  291.              */
  292.             destpc = reladdr( instructp+length )
  293.                 - (unsigned long) textspace;
  294.             if ( destpc >= s_lowpc && destpc <= s_highpc ) {
  295.             childp = nllookup( destpc );
  296. #            ifdef DEBUG
  297.                 if ( debug & CALLDEBUG ) {
  298.                 printf( "[findcall]\tdestpc 0x%x" , destpc );
  299.                 printf( " childp->name %s" , childp -> name );
  300.                 printf( " childp->value 0x%x\n" ,
  301.                     childp -> value );
  302.                 }
  303. #            endif DEBUG
  304.             if ( childp -> value == destpc ) {
  305.                 /*
  306.                  *    a hit
  307.                  */
  308.                 addarc( parentp , childp , (long) 0 );
  309.                 length += operandlength( instructp + length );
  310.                 continue;
  311.             }
  312.             goto botched;
  313.             }
  314.             /*
  315.              *    else:
  316.              *    it looked like a callf,
  317.              *    but it wasn't to anywhere.
  318.              */
  319.             goto botched;
  320.         default:
  321.         botched:
  322.             /*
  323.              *    something funny going on.
  324.              */
  325. #            ifdef DEBUG
  326.             if ( debug & CALLDEBUG ) {
  327.                 printf( "[findcall]\tbut it's a botch\n" );
  328.             }
  329. #            endif DEBUG
  330.             length = 1;
  331.             continue;
  332.         }
  333.     }
  334.     }
  335. }
  336.